<?php
/**
 * 注意：本内容仅限于博也公司内部传阅,禁止外泄以及用于其他的商业目的
 * @author    hebidu<346551990@qq.com>
 * @copyright 2018 www.itboye.com Boye Inc. All rights reserved.
 * @link      http://www.itboye.com/
 * @license   http://www.opensource.org/licenses/mit-license.php MIT License
 * Revision History Version
 ********1.0.0********************
 * file created @ 2018-03-12 15:56
 *********************************
 ********1.0.1********************
 *
 *********************************
 */

namespace by\component\tailong_bank\api;


use by\component\tailong_bank\helper\AesHelper;
use by\infrastructure\base\CallResult;
use by\infrastructure\helper\CallResultHelper;
use Curl\Curl;
use Psr\SimpleCache\CacheInterface;

/**
 * Class BaseApi
 * @property CacheInterface $cacheTool
 * @package by\component\tailong_bank\api
 */
class BaseApi
{
    private $service;
    private $appID;
    private $seqNO;
    private $signMethod;
    private $encryptMethod;
    private $appAccessToken;
    private $sign;
    private $reqData;

    private $cacheTool;

    /**
     * @param $key
     * @param $value
     * @param null $ttl
     * @return mixed
     * @throws \Psr\SimpleCache\InvalidArgumentException
     */
    public function setCache($key, $value, $ttl = null)
    {
        if ($this->cacheTool) {
            return $this->cacheTool->set($key, $value, $ttl);
        }
        return null;
    }

    /**
     * @param $key
     * @param null $default
     * @return mixed
     * @throws \Psr\SimpleCache\InvalidArgumentException
     */
    public function getCache($key, $default = null)
    {
        if ($this->cacheTool) {
            return $this->cacheTool->get($key, $default);
        }
        return null;
    }

    /**
     * BaseApi constructor.
     * @param CacheInterface $cacheTool
     */
    public function __construct(CacheInterface $cacheTool = null)
    {
        $this->cacheTool = $cacheTool;
    }

    /**
     * @return mixed
     */
    public function getService()
    {
        return $this->service;
    }

    /**
     * @param mixed $service
     */
    public function setService($service)
    {
        $this->service = $service;
    }

    /**
     * @return mixed
     */
    public function getReqData()
    {
        return $this->reqData;
    }

    /**
     * @param mixed $reqData
     */
    public function setReqData($reqData)
    {
        $this->reqData = $reqData;
    }

    /**
     * @return mixed
     */
    public function getAppID()
    {
        return $this->appID;
    }

    /**
     * @param mixed $appID
     */
    public function setAppID($appID)
    {
        $this->appID = $appID;
    }

    /**
     * @return mixed
     */
    public function getSeqNO()
    {
        return $this->seqNO;
    }

    /**
     * @param mixed $seqNO
     */
    public function setSeqNO($seqNO)
    {
        $this->seqNO = $seqNO;
    }

    /**
     * @return mixed
     */
    public function getSignMethod()
    {
        return $this->signMethod;
    }

    /**
     * @param mixed $signMethod
     */
    public function setSignMethod($signMethod)
    {
        $this->signMethod = $signMethod;
    }

    /**
     * @return mixed
     */
    public function getEncryptMethod()
    {
        return $this->encryptMethod;
    }

    /**
     * @param mixed $encryptMethod
     */
    public function setEncryptMethod($encryptMethod)
    {
        $this->encryptMethod = $encryptMethod;
    }

    /**
     * @return mixed
     */
    public function getAppAccessToken()
    {
        return $this->appAccessToken;
    }

    /**
     * @param mixed $appAccessToken
     */
    public function setAppAccessToken($appAccessToken)
    {
        $this->appAccessToken = $appAccessToken;
    }

    /**
     * @return mixed
     */
    public function getSign()
    {
        return $this->sign;
    }

    /**
     * @param mixed $sign
     */
    public function setSign($sign)
    {
        $this->sign = $sign;
    }

    /**
     * @param $url
     * @param $data
     * @return CallResult
     * @throws \ErrorException
     */
    public function post($url, $data)
    {
        $curl = new Curl();
        $curl->setHeader("content-type", "application/x-www-form-urlencoded");
        $curl->setHeader("charset", "utf-8");

        $curl->setOpt(CURLOPT_SSL_VERIFYPEER, false);
        $curl->setOpt(CURLOPT_SSL_VERIFYHOST, false);
        $resp = $curl->post($url, $data, true);
        $curl->close();
        if ($curl->error) {
            return CallResultHelper::fail($curl->errorMessage);
        }

        // 转化内容为 resp
        $data = json_decode($resp, JSON_OBJECT_AS_ARRAY);
        if (is_array($data) && array_key_exists('errorCode', $data)) {
            $errorCode = $data['errorCode'];
            $errorMsg = $data['errorMsg'];
            if ($errorCode != '000000') {
                return CallResultHelper::fail($errorMsg, $data, $errorCode);
            }
        }

        return CallResultHelper::success($data);
    }

    protected function encrypt($data, $password = '')
    {
        $encryptMethod = strtoupper($data['encryptMethod']);
        $reqData = json_encode($data['reqData'], JSON_UNESCAPED_UNICODE);
        if (strtoupper($encryptMethod) == 'AES') {
            $reqData = (AesHelper::opensslEncrypt($reqData, $password));
        }
        return $reqData;
    }

    protected function sign($data, $secret)
    {
        $signMethod = strtoupper($data['signMethod']);
        $reqData = json_encode($data['reqData'], JSON_OBJECT_AS_ARRAY);
        $seqNo = $data['seqNO'];

        if ($signMethod ==  'MD5') {
            return strtoupper(md5($reqData . $seqNo . $secret));
        }

        return '';
    }

    protected function checkSign($data, $secret)
    {
        if (is_string($data)) {
            $data = json_decode($data, JSON_OBJECT_AS_ARRAY);
        }

        $signMethod = strtoupper($data['signMethod']);
        $strData = '';
        if (array_key_exists('reqData', $data)) {
            $strData = $data['reqData'];
        }
        if (array_key_exists('rspData', $data)) {
            $strData = $data['rspData'];
        }
        $strData = json_encode($strData);
        $seqNo = array_key_exists('seqNO', $data) ? $data['seqNO'] : '';
        $sign = $data['sign'];

        if ($signMethod == 'MD5') {
            return $sign == strtoupper(md5($strData . $seqNo . $secret));
        }
        return false;
    }
}